/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2014-06-12
 * V4.0
 */
package com.jphenix.share.lang;

import com.jphenix.share.util.BaseUtil;
import com.jphenix.standard.docs.ClassInfo;
import com.jphenix.standard.lang.IResult;

import java.util.*;

/**
 * 按照先后顺序处理的Map容器
 * 
 * 2018-07-12 增加了 remove(index) 方法
 * 2019-09-10 增加了构造函数，可以用一行代码构造类实例并放入静态值
 * 2019-10-08 修改了containsValue方法，支持传入任意类型
 * 
 * @author 刘虻
 * 2012-11-14 下午6:26:13
 */
@ClassInfo({"2019-10-08 19:04","按照先后顺序处理的Map容器"})
public class SListMap<E> implements IResult,Collection<E> {

	protected Map<String,E>  valueMap    = new HashMap<String,E>(); //Map容器
	protected Vector<String> keyList     = new Vector<String>();    //主键序列容器
	
	//注意：这个序列中的索引序号与keyList不是一致的，这个容器仅用于迭代值
	protected Vector<E>      valueList   = new Vector<E>();         //值序列容器
	
	/**
	 * 构造函数
	 * @author 刘虻
	 */
	public SListMap() {
		super();
	}
	
	/**
	 * 构造函数
	 * @author MBG
	 */
	public SListMap(String[] keys,E[] vals) {
		super();
		if(keys==null || vals==null || keys.length<vals.length) {
			return;
		}
		for(int i=0;i<keys.length;i++) {
			valueMap.put(keys[i],vals[i]);
			keyList.add(keys[i]);
			valueList.add(vals[i]);
		}
	}

	/**
	 * 容器中的元素数量
	 * 刘虻
	 * 2012-11-14 下午6:50:16
	 * @return 元素数量
	 */
	@Override
    public synchronized int size() {
		return keyList.size();
	}

	/**
	 * 容器是否为空
	 * 刘虻
	 * 2012-11-14 下午6:50:04
	 * @return 是否为空
	 */
	@Override
    public synchronized boolean isEmpty() {
		return keyList.isEmpty();
	}

	/**
	 * 判断容器中是否存在该主键
	 * 刘虻
	 * 2012-11-14 下午6:49:43
	 * @param key 待判断的主键
	 * @return 是否存在该主键
	 */
	public synchronized boolean containsKey(String key) {
	    if(key==null) {
	        return false;
	    }
		return keyList.contains(key);
	}

	/**
	 * 判断容器中是否存在该值
	 * 刘虻
	 * 2012-11-14 下午6:49:19
	 * @param value 待判断的值
	 * @return 是否存在该值
	 */
	public synchronized boolean containsValue(Object value) {
	    if(value==null) {
	        return false;
	    }
		return valueMap.containsValue(value);
	}

	/**
	 * 获取指定值
	 * 刘虻
	 * 2012-11-14 下午6:49:05
	 * @param key 对应主键
	 * @return 对应的值
	 */
	public synchronized E get(String key) {
	    if(key==null) {
	        return null;
	    }
		return valueMap.get(key);
	}
	
	/**
	 * 通过索引值，移除指定元素值
	 * @param index  索引值
	 * @return       被移除的指定值
	 * 2018年7月12日
	 * @author MBG
	 */
	public synchronized E remove(int index) {
		if(index<0 || index>keyList.size()) {
			return null;
		}
		//移除指定主键
		String key = keyList.remove(index);
		return valueMap.remove(key);
	}
	
	/**
	 * 移出值
	 * 刘虻
	 * 2012-11-14 下午6:46:21
	 * @param key 对应的主键
	 * @return 对应的值
	 */
	public synchronized E remove(String key) {
	    if(key==null) {
	        return null;
	    }
		if(!valueMap.containsKey(key)) {
			return null;
		}
		//获取需要移除的返回值
		E value = valueMap.remove(key);
		keyList.remove(key);
		if(value!=null) {
			valueList.remove(value);
		}
		return value;
	}


	/**
	 * 放入值到容器中
	 * 刘虻
	 * 2012-11-14 下午6:48:16
	 * @param key		对应的主键
	 * @param value		对应的值
	 */
	public synchronized void put(String key, E value) {
	    if(key==null) {
	        return;
	    }
		if(!valueMap.containsKey(key)) {
		    keyList.add(key);
		}
		if(value==null) {
		    return;
		}
		//注意：valueList的索引并不是与keyList中一直，valueList仅用于值迭代
		valueList.add(value);
		valueMap.put(key,value);
		return;
	}
	
	
	/**
	 * 将序列容器中的值全部设置到当前类实例中
	 * @param listMap 指定序列容器
	 * 2015年2月13日
	 * @author 马宝刚
	 */
	public synchronized void putAll(SListMap<E> listMap) {
	    if(listMap==null) {
	        return;
	    }
		E value; // 值
		for (String key : listMap.keyList) {
			if (!keyList.contains(key)) {
				keyList.add(key);
			}
			value = listMap.get(key);
			if (value==null) {
				continue;
			}
			//注意：valueList的索引并不是与keyList中一直，valueList仅用于值迭代
			valueList.add(value);
			valueMap.put(key, value);
		}
	}

	/**
	 * 将容器中的值全部设置到当前类实例中
	 * @param map 指定容器
	 * 2015年2月13日
	 * @author 马宝刚
	 */
	public synchronized void putAll(Map<String,E> map) {
	    if(map==null) {
	        return;
	    }
	    //容器中的主键序列
	    List<String> keyList = BaseUtil.getMapKeyList(map);
	    E value; //值
	    for(String key:keyList) {
	        if(!keyList.contains(key)) {
	            keyList.add(key);
	        }
	        value = map.get(key);
	        if(value==null) {
	            continue;
	        }
			//注意：valueList的索引并不是与keyList中一直，valueList仅用于值迭代
			valueList.add(value);
	        valueMap.put(key,value);
	    }
	}

	/**
	 * 清空容器中的内容
	 * 刘虻
	 * 2012-11-14 下午6:47:52
	 */
	@Override
    public synchronized void clear() {
		keyList.clear();
		valueMap.clear();
		valueList.clear();
	}


	/**
	 * 获取值序列
	 * 刘虻
	 * 2012-11-14 下午6:47:40
	 * @return 值序列
	 */
	public synchronized List<E> values() {
		return valueList;
	}
	
	/**
	 * 覆盖方法
	 */
	@Override
    public String toString() {
	    //构建返回值
	    StringBuffer reSbf = new StringBuffer();
	    for(String key:keyList) {
	        reSbf.append("[").append(key).append(":").append(valueMap.get(key)+"] ");
	    }
	    return reSbf.toString();
	}
	
	/**
	 * 主键序列
	 * 刘虻
	 * 2012-11-18 下午2:19:44
	 * @return 主键序列
	 */
	public synchronized List<String> keys() {
		return keyList;
	}

	/**
	 * 将容器中的值转换为数组
	 * 刘虻
	 * 2012-11-14 下午6:50:36
	 * @return 对应的数组
	 */
	@Override
    @SuppressWarnings("unchecked")
	public synchronized E[] toArray() {
		return (E[])valueList.toArray();
	}
	
	/**
	 * 输出为普通的容器
	 * @return 普通的容器
	 * 2014年12月30日
	 * @author 马宝刚
	 */
	public synchronized Map<String,E> toMap(){
	    return valueMap;
	}

	/**
	 * 返回指定位置的元素
	 * 刘虻
	 * 2012-11-14 下午6:51:23
	 * @param index 元素索引
	 * @return 元素值
	 */
	public synchronized E get(int index) {
		return valueMap.get(keyList.get(index));
	}

	/**
	 * 返回指定位置的主键
	 * @param index 索引
	 * @return 元素值
	 * 2014-3-18
	 * @author 马宝刚
	 */
	public synchronized String getKey(int index) {
	    return keyList.get(index);
	}
	
	
	/**
	 * 移除指定位置的主键
	 * @param index 主键索引
	 * @return 主键值
	 * 2016年8月1日
	 * @author MBG
	 */
	public synchronized String removeKey(int index) {
		return keyList.remove(index);
	}
	
	
	/**
	 * 返回元素在容器中的位置（顺序）
	 * 刘虻
	 * 2012-11-14 下午6:52:17
	 * @param key 指定主键
	 * @return 在容器中的位置
	 */
	public synchronized int indexOf(String key) {
	    if(key==null) {
	        return -1;
	    }
		return keyList.indexOf(key);
	}

	/**
	 * 返回元素在容器中的位置（倒序）
	 * 刘虻
	 * 2012-11-14 下午6:52:17
	 * @param key 指定主键
	 * @return 在容器中的位置
	 */
	public synchronized int lastIndexOf(String key) {
	    if(key==null) {
	        return -1;
	    }
		return keyList.lastIndexOf(key);
	}

	/**
	 * 从容器中截取一段序列
	 * 刘虻
	 * 2012-11-14 下午6:53:51
	 * @param fromIndex 开始索引
	 * @param toIndex		结束索引
	 * @return 序列段
	 */
	public synchronized List<E> subValueList(int fromIndex, int toIndex) {
		ArrayList<E> reList = new ArrayList<E>(); //构建返回值
		//获取指定主键序列
		List<String> subKeyList = subKeyList(fromIndex,toIndex);
		for(int i=0;i<subKeyList.size();i++) {
			reList.add(valueMap.get(subKeyList.get(i)));
		}
		return reList;
	}
	
	/**
	 * 从容器中截取一段主键序列
	 * 刘虻
	 * 2012-11-20 上午10:32:39
	 * @param fromIndex 开始索引
	 * @param toIndex		结束索引
	 * @return 主键序列段
	 */
	public synchronized List<String> subKeyList(int fromIndex,int toIndex) {
		return keyList.subList(fromIndex,toIndex);
	}
	
    /**
     * 获取记录集
     * @return 记录集序列  element:HashMap:key:主键 value:值
     * 2014年6月12日
     * @author 马宝刚
     */
    @Override
    @SuppressWarnings({ "rawtypes", "unchecked" })
	public List<Map<String,String>> _getResult(){
    	//构建返回值
    	List<Map<String,String>> reList = new ArrayList<Map<String,String>>();
    	Map columnMap; //行记录集
    	for(String key:keyList) {
    		columnMap = new HashMap();
    		columnMap.put(key,valueMap.get(key));
    		reList.add(columnMap);
    	}
    	return reList;
    }

    //////// 以下是实现值的迭代接口方法 ////////////////////

    /**
     * 覆盖方法
     */
	@Override
	public boolean contains(Object o) {
		return valueList.contains(o);
	}

	/**
	 * 覆盖方法
	 */
	@Override
	public Iterator<E> iterator() {
		return valueList.iterator();
	}

	/**
	 * 覆盖方法
	 */
	@Override
	public <T> T[] toArray(T[] a) {
		return valueList.toArray(a);
	}

	/////////////////以下方法与迭代无关,不要使用//////////////////////
	/**
	 * 覆盖方法
	 */
	@Deprecated
	@Override
	public boolean add(E e) {
		return false;
	}

	/**
	 * 覆盖方法
	 */
	@Deprecated
	@Override
	public boolean remove(Object o) {
		return false;
	}

	/**
	 * 覆盖方法
	 */
	@Deprecated
	@Override
	public boolean containsAll(Collection<?> c) {
		return false;
	}

	/**
	 * 覆盖方法
	 */
	@Deprecated
	@Override
	public boolean addAll(Collection<? extends E> c) {
		return false;
	}

	/**
	 * 覆盖方法
	 */
	@Deprecated
	@Override
	public boolean removeAll(Collection<?> c) {
		return false;
	}

	/**
	 * 覆盖方法
	 */
	@Deprecated
	@Override
	public boolean retainAll(Collection<?> c) {
		return false;
	}
	
	/**
	 * 返回指定位置的主键
	 * @param index 索引
	 * @return 元素值
	 * 2014-3-18
	 * @author 马宝刚
	 */
	public synchronized String key(int index) {
	    return keyList.get(index);
	}
	
	
	/**
	 * 返回指定位置的元素
	 * 刘虻
	 * 2012-11-14 下午6:51:23
	 * @param index 元素索引
	 * @return 元素值
	 */
	public synchronized E value(int index) {
		return valueMap.get(keyList.get(index));
	}
}
